<template>
  <div>
    <a-row type="flex" justify="start">
      <a-col :span="4">
        <a-button type="primary" @click="handleAddRoleModalShow('新增角色', null)">
          新增角色
        </a-button>
      </a-col>
    </a-row>
    <a-row type="flex" justify="start">
      <a-col :span="4">
        <a-input v-model:value="roleQuery.name" placeholder="请输入角色名称" />
      </a-col>
      <a-col :span="4">
        <a-range-picker v-model:value="queryCreateTime" />
      </a-col>
      <a-col :span="4">
        <a-button type="primary" @click="onQuery(1, roleQuery.size)">搜索</a-button>
      </a-col>
    </a-row>
    <a-table :data-source="roleDataSource" :columns="roleColumns" row-key="id" :pagination="false">
      <template #operation="{ record }">
        <a-button type="primary" ghost @click="handleSetMenuModalShow(record.id)">
          设置菜单
        </a-button>
        <a-button type="primary" ghost @click="handleAddRoleModalShow('编辑角色', record)">
          编辑
        </a-button>
        <a-popconfirm
          v-if="roleDataSource.length"
          title="确认要删除吗"
          @confirm="onRoleDelete(record.id)"
        >
          <a-button type="danger" ghost>删除</a-button>
        </a-popconfirm>
      </template>
    </a-table>
    <a-row type="flex" justify="end">
      <a-pagination
        v-model:pageSize="roleQuery.size"
        v-model:current="roleQuery.current"
        v-model:total="roleQuery.total"
        show-size-changer
        @change="onQuery"
        @showSizeChange="onQuery"
      />
    </a-row>
    <a-modal v-model:visible="saveRoleVisible" :title="saveRoleTitle">
      <template #footer>
        <a-button key="back" @click="handleSaveRoleModalCancel">取消</a-button>
        <a-button key="submit" type="primary" :loading="saveRoleLoading" @click="handleAddRole">
          保存
        </a-button>
      </template>
      <a-form ref="saveRoleFormRef" :model="roleSaveForm" :rules="rules">
        <a-form-item label="角色名称" name="name">
          <a-input v-model:value="roleSaveForm.name" />
        </a-form-item>
      </a-form>
    </a-modal>
    <a-modal v-model:visible="setMenuVisible" title="设置菜单">
      <a-tree
        v-model:checkedKeys="selectMenuKeys"
        checkable
        :tree-data="menuDataSource"
        :replace-fields="menuReplaceFields"
      />
      <template #footer>
        <a-button key="back" @click="handleSetMenuModalCancel">取消</a-button>
        <a-button key="submit" type="primary" :loading="setMenuLoading" @click="handleSaveSetMenu">
          保存
        </a-button>
      </template>
    </a-modal>
  </div>
</template>
<script lang="ts">
import { defineComponent, reactive, toRaw, ref, UnwrapRef } from 'vue'
import { rolePage, addRole, deleteRole, updateRole } from '@/api/system/role'
import { Moment } from 'moment'
import { RolePageQuery, RolePageList } from '@/model/system/RolePage'
import { RoleAdd } from '@/model/system/RoleAdd'
import { message as Message } from 'ant-design-vue'
import { listByRole, saveSetMenu } from '@/api/system/menu'
import { ResMenuByRole, SetMenuReq } from '@/model/system/UpdateRoleMenu'

export default defineComponent({
  name: 'Role',
  components: {},
  setup() {
    // 分页
    // 临时变量查询时间
    const queryCreateTime = ref<Moment[]>([])
    // table列
    const roleColumns = [
      {
        title: '角色名称',
        dataIndex: 'name',
      },
      {
        title: '创建时间',
        dataIndex: 'createTime',
      },
      {
        title: '操作',
        dataIndex: 'operation',
        slots: { customRender: 'operation' },
      },
    ]
    // table数据
    const roleDataSource = ref<Array<RolePageList>>([])
    const rolePageQuery = new RolePageQuery()
    rolePageQuery.current = 1
    rolePageQuery.size = 10
    const roleQuery = reactive<RolePageQuery>(rolePageQuery)
    // 角色分页查询
    const onQuery = async (current: number, size: number | undefined) => {
      roleQuery.current = current
      roleQuery.size = size
      roleQuery.syncCreateTime(queryCreateTime.value)
      const rolePageRes = await rolePage(toRaw(roleQuery))
      roleQuery.total = rolePageRes.total
      roleDataSource.value = rolePageRes.records
    }
    // 初始化分页调用
    onQuery(1, 10)

    // 新增角色
    const saveRoleVisible = ref<boolean>(false)
    const saveRoleLoading = ref<boolean>(false)
    const saveRoleFormRef = ref()
    const saveRoleTitle = ref<string>('')
    const handleSaveRoleModalCancel = () => {
      saveRoleVisible.value = false
    }

    const roleSave = new RoleAdd()
    const roleSaveForm: UnwrapRef<RoleAdd> = reactive<RoleAdd>(roleSave)
    const handleAddRoleModalShow = (title: string, record: RolePageList | null) => {
      saveRoleTitle.value = title
      saveRoleVisible.value = true
      roleSaveForm.id = record?.id
      roleSaveForm.name = record?.name
    }

    const rules = {
      name: [
        { required: true, message: '角色名称必填', trigger: 'blur' },
        { min: 3, max: 10, message: '角色名称长度3-10位', trigger: 'blur' },
      ],
    }

    // 保存角色提交
    const handleAddRole = async () => {
      await saveRoleFormRef.value.validate()
      saveRoleLoading.value = true
      if (roleSaveForm.id != null) {
        await updateRole(toRaw(roleSaveForm))
      } else {
        await addRole(toRaw(roleSaveForm))
      }
      handleSaveRoleModalCancel()
      await onQuery(1, roleQuery.size)
      Message.success('新增角色成功')
      saveRoleLoading.value = false
    }
    // 删除角色
    const onRoleDelete = async (id: number) => {
      await deleteRole(id)
      await onQuery(1, 10)
    }

    // 设置角色
    const setMenuVisible = ref<boolean>(false)
    const setMenuLoading = ref<boolean>(false)
    const menuDataSource = ref<Array<ResMenuByRole>>([])
    const selectMenuKeys = ref<Array<number>>([])
    let activeRoleId: number | null = null
    const menuReplaceFields = {
      key: 'id',
      title: 'name',
    }
    const handleSetMenuModalShow = async (roleId: number) => {
      activeRoleId = roleId
      const queryMenu = {
        roleId: roleId,
      }
      menuDataSource.value = await listByRole(queryMenu)
      setMenuVisible.value = true
      selectMenuKeys.value = ResMenuByRole.getCheck(menuDataSource.value)
    }
    const handleSetMenuModalCancel = async () => {
      setMenuVisible.value = false
    }
    const handleSaveSetMenu = async () => {
      if (activeRoleId != null) {
        const setMenuReq = new SetMenuReq(activeRoleId, selectMenuKeys.value)
        setMenuLoading.value = true
        await saveSetMenu(setMenuReq)
        setMenuLoading.value = false
        setMenuVisible.value = false
        await onQuery(1, 10)
      }
    }
    return {
      roleColumns,
      roleDataSource,
      roleQuery,
      queryCreateTime,
      onQuery,
      saveRoleVisible,
      saveRoleLoading,
      handleSaveRoleModalCancel,
      handleAddRoleModalShow,
      roleSaveForm,
      rules,
      handleAddRole,
      saveRoleFormRef,
      saveRoleTitle,
      onRoleDelete,
      setMenuVisible,
      handleSetMenuModalShow,
      menuDataSource,
      menuReplaceFields,
      selectMenuKeys,
      handleSetMenuModalCancel,
      setMenuLoading,
      handleSaveSetMenu,
    }
  },
})
</script>

<style lang="scss"></style>
